package cn.itcast.p2p20.ui;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by Administrator on 2016/7/29.
 */
public class FlowLayout3 extends ViewGroup {


    private static final String TAG = "FlowLayout";

    public FlowLayout3(Context context) {
        super(context);
    }

    public FlowLayout3(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public FlowLayout3(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    //widthMeasureSpec不是控件的宽度，是控件的宽度和测量模式的组合
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int widthMeasureSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        //测量模式是为指定 mParentGiveMeWidth = 0
        int mParentGiveMeWidth = widthMeasureSpecMode == MeasureSpec.UNSPECIFIED ? Integer.MAX_VALUE : MeasureSpec.getSize(widthMeasureSpec);

        int heightMeasureSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int mParentGiveMeHeight = MeasureSpec.getSize(heightMeasureSpec);

        //自己测量的宽度和高度
        int mMeasureWidth = 0;
        int mMeasureHeigth = 0;

        int lastLineHeight = 0;
        int startX = getPaddingLeft();
        int startY = getPaddingTop();

        //遍历子控件进行测量
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {

            View childView = getChildAt(i);
            measureChild(childView, widthMeasureSpec, heightMeasureSpec);

            //计算自己测量的宽度和高度
            MarginLayoutParams layoutParams = (MarginLayoutParams) childView.getLayoutParams();
            //当子控件为GONE的时候不去显示，INVISIBLE 情况由ViewGroup已经处理
            if (childView.getVisibility() == GONE) {

                continue;
            }
            int childViewMeasuredWidth = childView.getMeasuredWidth();
            int childViewMeasuredHeight = childView.getMeasuredHeight();
            //换行，改变startX，startY
            //每个子控件的宽度需要加上leftMargin,rightMargin就是每个自己需要使用的宽度
            //int measuredWidth = getMeasuredWidth(); 需要在测量之后才会有值
            if (startX + childViewMeasuredWidth + layoutParams.leftMargin + layoutParams.rightMargin > /*measuredWidth*/mParentGiveMeWidth - getPaddingLeft() - getPaddingRight()) {//考虑内边距
                startX = getPaddingLeft();
                startY += lastLineHeight;
            }

            //累加startX
            startX += childViewMeasuredWidth + layoutParams.leftMargin + layoutParams.rightMargin;//累加宽度的时候考虑自己的leftMargin，rightMargin

            //每一行所占据的高度应该是一行当中最高的
            lastLineHeight = Math.max(lastLineHeight, childViewMeasuredHeight + layoutParams.topMargin + layoutParams.bottomMargin);//累加高度的时候考虑自己的topMargin，bottomMargin

            //测量的宽度mMeasureWidth， 所有行的最大值
            mMeasureWidth = Math.max(startX, mMeasureWidth);
        }

        mMeasureWidth += getPaddingRight();
        mMeasureHeigth = startY + lastLineHeight + getPaddingBottom();


        String widthMeasureSpecStr = MeasureSpec.toString(widthMeasureSpec);
        String heightMeasureSpecStr = MeasureSpec.toString(heightMeasureSpec);

        Log.d(TAG, "onMeasure() widthMeasureSpecStr--->" + widthMeasureSpecStr);
        Log.d(TAG, "onMeasure() heightMeasureSpecStr--->" + heightMeasureSpecStr);


        /// android:layout_width="wrap_content" ======》 widthMeasureSpecStr--->MeasureSpec: AT_MOST 320
        /// android:layout_height="match_parent"   android:layout_height="300dp" ======》  heightMeasureSpecStr--->MeasureSpec: EXACTLY 319

        // 当前空间的父控件是ScrollView  控件的高度的测量模式是UNSPECIFIED  heightMeasureSpecStr--->MeasureSpec: UNSPECIFIED 0

        // 当前控件的父控件是HorizontalScrollView  控件的宽度的测量模式 widthMeasureSpecStr--->MeasureSpec: UNSPECIFIED 0


        //super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(getMeasureSize(widthMeasureSpecMode, mParentGiveMeWidth, mMeasureWidth),
                getMeasureSize(heightMeasureSpecMode, mParentGiveMeHeight, mMeasureHeigth));
    }

    /**
     * @param measureMode       测量模式
     * @param mParentGiveMeSize 父控件分配给自己的宽度或高度
     * @param mMeasureSize      自己测量的宽度或高度，宽度：每一行子控件累计的最大值， 高度：所有行的高的累加
     * @return
     */
    public int getMeasureSize(int measureMode, int mParentGiveMeSize, int mMeasureSize) {

        if (measureMode == MeasureSpec.EXACTLY) {

            return mParentGiveMeSize;
        } else if (measureMode == MeasureSpec.AT_MOST) {//wrap_content,  就自子控件的宽度或者高度为准但是宽度和高度不能超过父控件做给的宽度和高度

            return Math.min(mParentGiveMeSize, mMeasureSize);
        } else {//UNSPECIFIED

            return mMeasureSize;
        }
    }


    /*

            考虑每个子控件的margin值， 每个子控件占据的宽度要加上marginLeft marginRight, 高度加上marginTop,marginBottom
     */
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        //考虑内边距
        int startX = getPaddingLeft();
        int startY = getPaddingTop();
        int lastLineHeight = 0;
        int measuredWidth = getMeasuredWidth();
        int measuredHeight = getMeasuredHeight();
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {

            View childView = getChildAt(i);
            MarginLayoutParams layoutParams = (MarginLayoutParams) childView.getLayoutParams();
            //当子控件为GONE的时候不去显示，INVISIBLE 情况由ViewGroup已经处理
            if (childView.getVisibility() == GONE) {

                continue;
            }
            int childViewMeasuredWidth = childView.getMeasuredWidth();
            int childViewMeasuredHeight = childView.getMeasuredHeight();
            //换行，改变startX，startY
            //每个子控件的宽度需要加上leftMargin,rightMargin就是每个自己需要使用的宽度
            if (startX + childViewMeasuredWidth + layoutParams.leftMargin + layoutParams.rightMargin > measuredWidth - getPaddingLeft() - getPaddingRight()) {//考虑内边距
                startX = getPaddingLeft();
                startY += lastLineHeight;
            }

            int childLeft = startX + layoutParams.leftMargin;//考虑marginLeft
            int childTop = startY + layoutParams.topMargin;//考虑topMargin
            int childRight = childLeft + childViewMeasuredWidth;
            int childBottom = childTop + childViewMeasuredHeight;
            childView.layout(childLeft, childTop, childRight, childBottom);
            //累加startX
            startX += childViewMeasuredWidth + layoutParams.leftMargin + layoutParams.rightMargin;//累加宽度的时候考虑自己的leftMargin，rightMargin

            //每一行所占据的高度应该是一行当中最高的
            lastLineHeight = Math.max(lastLineHeight, childViewMeasuredHeight + layoutParams.topMargin + layoutParams.bottomMargin);//累加高度的时候考虑自己的topMargin，bottomMargin
        }

    }


}
